package densetsu.view;

import java.awt.Color;
import java.awt.Dimension;
import java.awt.Graphics;
import java.awt.Graphics2D;
import java.awt.RenderingHints;
import java.awt.geom.Rectangle2D;
import java.awt.image.BufferedImage;

import javax.swing.JPanel;

import densetsu.model.Model;
import densetsu.model.map.GameMap;
import densetsu.model.players.Player;
import densetsu.view.shapes.EnemyShape;
import densetsu.view.shapes.PlayerShape;
import densetsu.view.shapes.ShapeFactory;

/**
 * Will contain the actual game graphics.
 * 
 * @author Koen
 * 
 */
public class GamePanel extends JPanel {

	private static final long serialVersionUID = 6656230377738046433L;

	private Model model;
	private BufferedImage bufferedImage;
	public static final int TILESIZE = GameView.SIZE / GameMap.SIZE;

	public GamePanel ( Model model ) {
		super ( );
		setPreferredSize ( new Dimension ( GameView.SIZE, GameView.SIZE ) );
		setFocusable ( true ); // Not sure if needed, just putting for safety.
								// Can always remove later.
		bufferedImage = new BufferedImage ( GameView.SIZE, GameView.SIZE,
				BufferedImage.TYPE_INT_RGB );
		this.model = model;
	}

	@Override
	public void paint ( Graphics g ) {
		super.paint ( g );
		Graphics2D g2 = ( Graphics2D ) g;
		g2.setRenderingHint ( RenderingHints.KEY_ANTIALIASING,
				RenderingHints.VALUE_ANTIALIAS_ON );
		// Paint to the buffered image
		paintToBufferedImage ( );
		// Paint buffered image to screen
		g2.drawImage ( bufferedImage, null, 0, 0 );
	}

	private void paintToBufferedImage ( ) {
		Graphics2D bufferGraphics = ( Graphics2D ) bufferedImage.getGraphics ( );
		bufferGraphics.setRenderingHint ( RenderingHints.KEY_ANTIALIASING,
				RenderingHints.VALUE_ANTIALIAS_ON );
		// Fill up with empty rectangle first
		bufferGraphics.fillRect ( 0, 0, GameView.SIZE, GameView.SIZE );
		// print map
		for ( int y = 0; y < GameMap.SIZE; y++ ) {
			for ( int x = 0; x < GameMap.SIZE; x++ ) {
				Rectangle2D thisTile = new Rectangle2D.Double ( x * TILESIZE, y
						* TILESIZE, TILESIZE, TILESIZE );
				bufferGraphics.setColor ( model.getMap ( ).getTileAt ( x, y )
						.getTileColor ( ) );
				bufferGraphics.fill ( thisTile );
				bufferGraphics.setColor ( Color.black );
				bufferGraphics.draw ( thisTile );
			}
		}
		// Print player:
		bufferGraphics.setColor ( PlayerShape.COLOR );
		bufferGraphics
				.fill ( ShapeFactory.getPlayerShape ( model.getPlayer ( )
						.getX ( ) * TILESIZE, model.getPlayer ( ).getY ( )
						* TILESIZE ) );
		// Print enemies
		bufferGraphics.setColor ( EnemyShape.COLOR );
		for ( Player p : model.getEnemies ( ) ) {
			bufferGraphics.fill ( ShapeFactory.getEnemyShape ( p.getX ( ),
					p.getY ( ) ) );
		}
	}
}
